package cn.dawn.webcollector.generator;

import java.io.UnsupportedEncodingException;

import cn.dawn.webcollector.model.CrawlDatum;
import cn.dawn.webcollector.util.BerkeleyDBUtils;
import cn.dawn.webcollector.util.Config;

import com.sleepycat.je.Cursor;
import com.sleepycat.je.CursorConfig;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;

/**
 * <p>Title:XXXX</p>
 * <p>Description:XXXXXXXX</p>
 * @Copyright:Copyright (c) 2015
 * @Author:wangxiao
 * @Version:1.0
 * @Time:2015年10月10日
 */
public class StandardGenerator implements Generator {

	Cursor cursor = null;
	Database crawldbDatabase = null;
	Environment env;
	protected int totalGenerate = 0;
	protected Integer topN = null;
	protected int maxRetry = Config.MAX_RETRY;
	
	public StandardGenerator(Environment env) {
		this.env = env;
		totalGenerate = 0;
	}

	@Override
	public CrawlDatum next() {
		if (topN != null) {
			if (totalGenerate >= topN) {
				return null;
			}
		}
		if (cursor == null) {
			crawldbDatabase = env.openDatabase(null, Config.BDB_CRAWLDB, BerkeleyDBUtils.defaultDBConfig);
			cursor = crawldbDatabase.openCursor(null, CursorConfig.DEFAULT);
		}
		while (true) {

			DatabaseEntry key = new DatabaseEntry();
			DatabaseEntry value = new DatabaseEntry();
			
			if (cursor.getNext(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
				try {
					CrawlDatum datum = new CrawlDatum(key, value);
					if (datum.getStatus() == CrawlDatum.STATUS_DB_FETCHED) {
						continue;
					} else {
						if (datum.getRetry() >= maxRetry) {
							continue;
						}
						totalGenerate++;
						return datum;
					}
				} catch (UnsupportedEncodingException ex) {
					continue;
				}
			} else {
				return null;
			}
		}
	}

	public int getTotalGenerate() {
		return totalGenerate;
	}

	public Integer getTopN() {
		return topN;
	}

	public void setTopN(Integer topN) {
		this.topN = topN;
	}

	public int getMaxRetry() {
		return maxRetry;
	}

	public void setMaxRetry(int maxRetry) {
		this.maxRetry = maxRetry;
	}

	public void close() {
		cursor.close();
		crawldbDatabase.close();
	}
}
